home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / utils / stlogin4.lzh / TAIL.C < prev    next >
C/C++ Source or Header  |  1993-07-24  |  2KB  |  123 lines

  1. /* Simple UNIX like tail on ATARI ST. Kees Lemmens; Juli 1993
  2.  
  3.    Usage: tail [+|-nr] <filename>
  4.    
  5.    Default is currently to list the last 10 lines from the file,
  6.    which is equal to "tail -10 <filename>"
  7.  
  8.    Also works with pipes like in "tail file | more".
  9.  
  10.    Any questions or suggestions about this program can be send to:
  11.    lemmens@dv.twi.tudelft.nl
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "ux_misc.h"
  18.  
  19. #define MAXLEN    255
  20. #define DEFTAIL -10
  21.  
  22. static char buffer[MAXLEN];
  23.  
  24. void TailFromEnd(int fp,long len)
  25. {    size_t cumsize,readsize;
  26.     size_t *position;
  27.     size_t x,y;
  28.  
  29.     position = (size_t *)calloc(len+1,sizeof(size_t));
  30.     /* check for out of memory */
  31.  
  32.     cumsize = 0L;
  33.     do
  34.     {    readsize = read(fp,buffer,MAXLEN);
  35.         for(x=0;x<readsize;x++)
  36.             if(buffer[x] == '\n')
  37.             {    for(y=len;y>0;y--)    /* shift all previous values */
  38.                     position[y] = position[y-1];
  39.  
  40.                 position[0] = cumsize + x;    /* store new value */
  41.             }
  42.         cumsize += readsize;
  43.     }while(readsize == MAXLEN);
  44.  
  45.     if(position[len] == 0L)
  46.         lseek(fp,0,SEEK_SET);    /* rewind to begin of file */
  47.     else if(lseek(fp,position[len],SEEK_SET) == -1)
  48.         exit(1);
  49.  
  50.     free(position);
  51. }
  52.  
  53. void TailFromStart(int fp,long len)
  54. {    size_t cumsize,readsize;
  55.     size_t position;
  56.     size_t x;
  57.  
  58.     /* just skip the first <len> lines */
  59.  
  60.     cumsize = 0L;
  61.     do
  62.     {    readsize = read(fp,buffer,MAXLEN);
  63.         for(x=0;x<readsize && len >0;x++)
  64.             if(buffer[x] == '\n')
  65.             {    len--;
  66.                 position = cumsize + x;
  67.             }
  68.         cumsize += readsize;
  69.     
  70.     }while(readsize == MAXLEN && len>0);
  71.  
  72.     lseek(fp,position,SEEK_SET);
  73. }
  74.  
  75. void ListTail(int fp)
  76. {    size_t readsize;
  77.  
  78.     do
  79.     {    readsize = read(fp,buffer,MAXLEN);
  80.         write(fileno(stdout),buffer,readsize);
  81.         
  82.     } while(readsize == MAXLEN);
  83. }
  84.  
  85. void main(int argc,char *argv[]) 
  86. {    int fp;
  87.     long len=DEFTAIL;
  88.     char *filename = NULL;
  89.  
  90.     while(--argc>0)        /* parse options */
  91.     {    if(*argv[1] == '-' || *argv[1] == '+')
  92.         {    if((len=atol(argv[1])) == 0)
  93.             {    fputs("Illegal value !\n",stderr);
  94.                 exit(1);
  95.             }
  96.             ++argv;
  97.         }
  98.         else
  99.             filename = argv[1];
  100.     }
  101.  
  102.     if (filename != NULL)
  103.     {    ux2dos(filename);    /* convert slashes */
  104.         if ((fp = open(filename,O_RDONLY)) < 0)
  105.         {    fputs("\nCan't open file\n",stderr);
  106.             exit(1);
  107.         }
  108.     }
  109.     else
  110.         fp = fileno(stdin);
  111.  
  112.     if(len  > 0)
  113.         TailFromStart(fp,len);
  114.     else
  115.         TailFromEnd(fp,(-len));
  116.     
  117.     ListTail(fp);
  118.  
  119.     if (fp != fileno(stdin))
  120.         close(fp);
  121.     exit(0);
  122. }
  123.